\subsection{Integración de OpenSteer, Bullet y Ogre.}

Para el comportamiento de los enemigos (zombis) se ha utilizado la biblioteca 
OpenSteer.

OpenSteer proporciona una biblioteca de funciones que implementan diferentes 
comportamientos. Estos comportamientos son representados por un vector de 
dirección o fuerza de orientación.

OpenSteer permite la integración con el código existente de diversas formas. 
Una de ellas es la utilización de “Mixin Classes”. Se trata de clases cuya 
superclase es una plantilla, de modo que pueden heredar de cualquier clase ya 
existente, siempre que implementen ciertas interfaces. También se puede heredar 
directamente de las clases proporcionadas.

En el caso de Shadow City, se han utilizado ambas formas, tal y como se hace en 
la clase de ejemplo SimpleVehicle proporcionada por OpenSteer.

Para utilizar SteerLibraryMixin se han de implementar la interfaz definida en 
AbstractVehicle (la cual a su vez requiere la implementación de 
AbstractLocalSpace).

AbstractVehicle representa un vehículo móvil con una velocidad, una dirección y 
un radio. Por su parte, AbstractLocalSpace representa un sistema de coordenadas 
local, con una base ortonormal cuya orientación depende de la dirección en la 
que se mueve el vehículo, así como la posición global de este en el espacio.

Para integrar OpenSteer y Bullet se toma como vehículo un cuerpo rígido de 
Bullet sobre el que se aplicaran los vectores de fuerza u orientación 
proporcionados por SteerLibraryMixin. De este modo el diagrama de clases 
resultante es el de la figura \ref{BulletVehicle}.

\begin{figure}[h]
\centering
\includegraphics[width = 12 cm]{BulletVehicle.eps}
\caption{Diagrama de clases de BulletVehicle.}
\label{BulletVehicle}
\end{figure}

OpenSteer proporciona una implementación de la interfaz AbstractLocalSpace. Se 
estudio la viabilidad de reutilizar dicha implementación y se descubrió que 
puede utilizarse sobreescribiendo tan solo los métodos relacionados con la 
posición del vehículo.

Gracias a esto, no solo se puede reutilizar el código, sino que además se 
proporciona a OpenSteer una retroalimentación desde el cuerpo rígido, el cual 
está sometido a una serie de restricciones físicas que no son contempladas por 
OpenSteer pero si por Bullet (como por ejemplo que dos vehículos no pueden 
ocupar el mismo espacio al mismo tiempo).

La implementación de AbstractVehicle se lleva a cabo en la clase propia 
BulletVehicle. Esta clase implementa los métodos de AbstractVehicle.

No todos los métodos de AbstractVehicle son utilizados por SteerLibraryMixin, 
por lo que BulletVehicle implementa tan solo los que utiliza (se descubren 
estudiando el archivo de cabecera de SteerLibraryMixin) así como algunos otros 
susceptibles de ser reutilizados para la implementación del juego.

BulletVehicle tiene como miembro un puntero a un cuerpo rígido, el cual será 
sometido a las fuerzas de orientación calculadas por OpenSteer.

Estas fuerzas son aplicadas, cumpliendo una serie de restricciones dadas por 
otros atributos de la clase (velocidad y fuerza máximas) en el método 
applySteeringForce.

De este modo, heredando de la clase BulletVehicle e implementando el método 
update (en donde se utilizarán las funciones de SteerLibraryMixin para calcular 
los vectores de fuerza, los cuales se aplicaran con la función 
applySteeringForce) se logra la integración de OpenSteer con Bullet.

Para integrar todo esto con Ogre, simplemente se implementa la interfaz 
btMotionState para aplicar al objeto visible de Ogre la matriz de 
transformación del objeto físico de Bullet.

